
import UIKit
import Photos

public extension UIColor {
    
    // hex sample: 0xf43737
    convenience init(hex: Int, alpha: Double = 1.0) {
        self.init(red: CGFloat((hex>>16)&0xFF)/255.0, green: CGFloat((hex>>8)&0xFF)/255.0, blue: CGFloat((hex)&0xFF)/255.0, alpha: CGFloat(255 * alpha) / 255)
    }
    
    convenience init(hexString: String, alpha: Double = 1.0) {
        let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
        var int = UInt32()
        Scanner(string: hex).scanHexInt32(&int)
        let r, g, b: UInt32
        switch hex.count {
        case 3: // RGB (12-bit)
            (r, g, b) = ((int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
        case 6: // RGB (24-bit)
            (r, g, b) = (int >> 16, int >> 8 & 0xFF, int & 0xFF)
        default:
            (r, g, b) = (1, 1, 0)
        }
        self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(255 * alpha) / 255)
    }
    
    convenience init(r: CGFloat, g: CGFloat, b: CGFloat) {
        self.init(red: (r/255), green: (g/255), blue: (b/255), alpha: 1)
    }
    
    convenience init(r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) {
        self.init(red: (r/255), green: (g/255), blue: (b/255), alpha: a)
    }
}

public extension PHAsset {
    var assetId: String? {
        return String(format: "%@%f", localIdentifier, creationDate?.timeIntervalSince1970 ?? 0)
    }
}

public extension CGSize {
    func scale(for targetSize: CGSize) -> CGSize {
        let widthRatio  = targetSize.width  / self.width
        let heightRatio = targetSize.height / self.height
        
        var newSize: CGSize
        if(widthRatio > heightRatio) {
            newSize = CGSize(width: self.width * heightRatio, height: self.height * heightRatio)
        } else {
            newSize = CGSize(width: self.width * widthRatio, height: self.height * widthRatio)
        }
        return newSize
    }
}

public extension UITextField {
    func clearButtonWithImage(_ image: UIImage) {
        let clearButton = UIButton(type: .custom)
        clearButton.setImage(image, for: .normal)
        clearButton.frame = CGRect(x: 0, y: 0, width: 15, height: 15)
        clearButton.contentMode = .scaleAspectFit
        clearButton.addTarget(self, action: #selector(self.clear(sender:)), for: .touchUpInside)
        self.rightView = clearButton
        self.rightViewMode = .whileEditing
    }
    
    @objc func clear(sender : AnyObject) {
        self.text = ""
    }
    
    func leftViewWithImage(_ image: UIImage, contentMode: UIView.ContentMode = .center, offset: CGFloat = 12) {
        let leftView = UIImageView(image: image)
        if let size = leftView.image?.size {
            leftView.frame = CGRect(x: 0, y: 0, width: size.width + offset * 2, height: size.height)
        }
        leftView.contentMode = contentMode
        
        self.leftView = leftView
        self.leftViewMode = .always
    }
}


public extension UIApplication {
    
    var screenShot: UIImage?  {
        if let window = keyWindow {
            let scale = UIScreen.main.scale
            let bounds = window.bounds
            UIGraphicsBeginImageContextWithOptions(bounds.size, false, scale);
            if let _ = UIGraphicsGetCurrentContext() {
                window.drawHierarchy(in: bounds, afterScreenUpdates: true)
                let screenshot = UIGraphicsGetImageFromCurrentImageContext()
                UIGraphicsEndImageContext()
                return screenshot
            }
        }
        return nil
    }
    
//    func snapshotView() -> UIView? {
//        if let window = keyWindow {
//            let snapshot = window.snapshotView(afterScreenUpdates: true)
//            if #available(iOS 11.0, *), let oldSnapshot = snapshot {
//                // in iOS 11, the snapshot taken by snapshotView(afterScreenUpdates) won't contain a container view
//                return SnapshotWrapperView(contentView: oldSnapshot)
//            } else {
//                return snapshot
//            }
//        }
//        return nil
//    }
    
    var statusBarView: UIView? {
        return value(forKey: "statusBar") as? UIView
    }
}


public extension UIWindow {
    
    func set(rootViewController newRootViewController: UIViewController?, withTransition transition: CATransition? = nil) {
        guard let newRootViewController = newRootViewController else {
            return
        }
        
        let previousViewController = rootViewController
        
        if let transition = transition {
            // Add the transition
            layer.add(transition, forKey: kCATransition)
        }
        
        rootViewController = newRootViewController
        
        // Update status bar appearance using the new view controllers appearance - animate if needed
        if UIView.areAnimationsEnabled {
            UIView.animate(withDuration: CATransaction.animationDuration()) {
                newRootViewController.setNeedsStatusBarAppearanceUpdate()
            }
        } else {
            newRootViewController.setNeedsStatusBarAppearanceUpdate()
        }
        
        /// The presenting view controllers view doesn't get removed from the window as its currently transistioning and presenting a view controller
        if let transitionViewClass = NSClassFromString("UITransitionView") {
            for subview in subviews where subview.isKind(of: transitionViewClass) {
                subview.removeFromSuperview()
            }
        }
        if let previousViewController = previousViewController {
            // Allow the view controller to be deallocated
            previousViewController.dismiss(animated: false) {
                // Remove the root view in case its still showing
                previousViewController.view.removeFromSuperview()
            }
        }
    }
    
}


// MARK: - block for UIControl
public class ClosureSleeve {
    let closure: ()->()
    
    init (_ closure: @escaping ()->()) {
        self.closure = closure
    }
    
    @objc func invoke () {
        closure()
    }
}

public extension UIControl {
    public func add (for controlEvents: UIControl.Event, _ closure: @escaping ()->()) {
        let sleeve = ClosureSleeve(closure)
        addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
        objc_setAssociatedObject(self, String(format: "[%d]", arc4random()), sleeve, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
    }
}

public extension UIFont {
    
    enum PingFangSC {
        case ultralight
        case regular
        case semibold
        case thin
        case light
        case medium
    }

    public class func size(_ size: CGFloat, type: PingFangSC = .regular) -> UIFont {
        
        var font: UIFont?
        switch type {
        case .ultralight:
            font = UIFont(name: "PingFangSC-Ultralight", size: size)
        case .regular:
            font = UIFont(name: "PingFangSC-Regular", size: size)
        case .semibold:
            font =  UIFont(name: "PingFangSC-Semibold", size: size)
        case .thin:
            font = UIFont(name: "PingFangSC-Thin", size: size)
        case .light:
            font = UIFont(name: "PingFangSC-Light", size: size)
        case .medium:
            font = UIFont(name: "PingFangSC-Medium", size: size)
        }
        if font == nil {
            font = UIFont.systemFont(ofSize: size)
        }
        return font!
    }
}

public extension UILabel {
    func numberOfMaxLines() -> Int {
        let maxSize = CGSize(width: frame.size.width, height: CGFloat(Float.infinity))
        let charSize = font.lineHeight
        let text = (self.text ?? "") as NSString
        let textSize = text.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, attributes: [.font: font], context: nil)
        let lines = Int(textSize.height/charSize)
        return lines
    }
}


public extension AVPlayer {
    var isPlaying: Bool {
        return rate != 0 && error == nil
    }
}


